home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.unix
- From: vesper@kong.gsfc.nasa.gov (Greg Vesper - 520.9)
- Subject: v26i103: cputt - cpu status monitor for sunos, V2.3, Part01/01
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: vesper@kong.gsfc.nasa.gov (Greg Vesper - 520.9)
- Posting-Number: Volume 26, Issue 103
- Archive-Name: cputt-2.3/part01
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: MANIFEST Makefile README UNSHAR.HDR cputt.c cputt.h
- # getcmd.c globals.c hash.c init.c routines.c
- # Wrapped by vixie@gw.home.vix.com on Tue Apr 6 03:42:49 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(455 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1 This shipping list
- X Makefile 1
- X README 1
- X UNSHAR.HDR 1
- X cputt.c 1
- X cputt.h 1
- X getcmd.c 1
- X globals.c 1
- X hash.c 1
- X init.c 1
- X routines.c 1
- END_OF_FILE
- if test 455 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(484 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- PROG = cputt
- OBJS = globals.o init.o getcmd.o hash.o routines.o cputt.o
- CC = cc
- CFLAGS = -Isys
- LIBS = -lkvm
- DIRINSTALL = /usr/local/bin
- X
- all: $(PROG)
- X
- X.c.o:
- X $(CC) $(CFLAGS) -c -O $<
- X
- X$(OBJS): cputt.h
- X
- X$(PROG): $(OBJS)
- X $(CC) -o $@ $(OBJS) $(LIBS)
- X
- install: $(PROG)
- X strip $(PROG)
- X cp $(PROG) $(DIRINSTALL)/$(PROG)
- X /etc/chown root $(DIRINSTALL)/$(PROG)
- X chgrp kmem $(DIRINSTALL)/$(PROG)
- X chmod 2755 $(DIRINSTALL)/$(PROG)
- X
- clean:
- X rm -f $(OBJS) $(PROG)
- END_OF_FILE
- if test 484 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(3874 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X Cputt - CPU Top Ten monitor for SUNOS 4.1.1
- X ===========================================
- X Version 2.3
- X
- DISCLAIMER:
- X
- X This software has no warranty whatsoever, explicit or implicit.
- X The author and his employer shall not be held liable for any
- X damage, direct or indirect, resulting from the use of this
- X software. That being said, feel free to use it, its a handy
- X little utility.
- X
- PURPOSE:
- X
- X Cputt is a cpu monitoring utility for SunOS 4.1.1. It gives you a
- X continuous update of the top ten cpu-using processes on your
- X system.
- X
- CHANGES:
- X
- X Version 2.3 contains a bug fix which allows Cputt to run on Sun 3's.
- X It now assigns default values if invoked without parameters. The
- X source has been neatened up as well.
- X
- IMPLEMENTATION:
- X
- X Cputt takes two snapshots of the kernel process table, sleeping
- X for a user supplied number of seconds in between the two
- X snapshots. It calculates cpu usage for each process over that
- X interval and prints out the results. Execution continues for a
- X user supplied number of iterations.
- X
- USAGE:
- X
- X Cputt should be invoked with two arguments as follows:
- X
- X cputt <length of interval> <number of iterations>
- X
- X Cputt prints a sorted list of cpu intensive processes as follows:
- X
- X PID USER CPU MEM COMMANDS <active processes> <ptable size>
- X
- INSTALLATION:
- X
- X Cputt should compile on any system running SunOS 4.1.1. Check
- X the #define values in cputt.h before compiling. The only one
- X you need to change is MAXUSERS which should be two times the
- X number of /etc/passwd entries on your machine. Just type
- X 'make' to compile, 'make install' to install. You must be root
- X to install Cputt. The default destination is /usr/local/bin.
- X
- SUGGESTION:
- X
- X Cputt becomes more and more processor intensive as the length of the
- X interval between process table lookups decreases. Thus a first
- X arguement of less than 4 is probably not real useful. I usually
- X invoke it with one of the following:
- X
- X cputt 5 10 - for short term monitoring of cpu usage (default)
- X cputt 10 100 - for long term monitoring of cpu usage
- X cputt 20 1000 - for real long term monitoring of cpu usage
- X
- ACKNOWLEDGEMENTS:
- X
- X The idea for Cputt came from Larry Schuler, a friend and co-worker.
- X The implementation for Cputt was largely dependent on J. Robert Ward's
- X 'sps' utility. I used Robert's source code to learn how to make the
- X appropriate system calls for interrogating the kernel process table.
- X The rest of the algorithm and implementation are my own.
- X
- IMPROVEMENTS:
- X
- X I've used all the shortcuts I know to make Cputt as trim as possible.
- X Floating point arithmetic is kept to a bare minimum. Internal data
- X structures are allocated dynamically based on the changing status of
- X the process table. Command arguements for each process are kept in
- X core instead of being re-evaluated at each iteration. The sort table
- X contains only active processes and no extraneous information. The
- X kernel reads account for the bulk of Cputt's processing overhead and
- X I'm unaware of anyway to alleviate this cost. If anyone has any well
- X considered suggestions about how I can improve the implemenation and
- X performance of Cputt, I would like to hear them.
- X
- COPYRIGHT:
- X
- X Feel free to distribute Cputt to any interested parties. Please
- X provide a copy of this README with any distribution.
- X
- X:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- X Greg Vesper Code 520.9
- X Goddard Space Flight Center
- X vesper@kong.gsfc.nasa.gov
- X Greenbelt, Maryland
- X
- X"As He died to make men holy, let us live to make men free.
- X:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- END_OF_FILE
- if test 3874 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'UNSHAR.HDR' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'UNSHAR.HDR'\"
- else
- echo shar: Extracting \"'UNSHAR.HDR'\" \(1160 characters\)
- sed "s/^X//" >'UNSHAR.HDR' <<'END_OF_FILE'
- Return-Path: vesper@kong.gsfc.nasa.gov
- Received: by cognition.pa.dec.com; id AA22597; Mon, 27 Apr 92 08:07:55 -0700
- Received: by inet-gw-2.pa.dec.com; id AA22182; Mon, 27 Apr 92 08:07:50 -0700
- Received: from relay2.UU.NET by rodan.UU.NET with SMTP (5.61/UUNET-mail-drop) id AA01224; Mon, 27 Apr 92 11:07:46 -0400
- Received: from lego.gsfc.nasa.gov by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA11514; Mon, 27 Apr 92 11:07:48 -0400
- Received: from kong.gsfc.nasa.gov by lego.gsfc.nasa.gov (5.61/1.35)id AA20539; Mon, 27 Apr 92 11:07:28 -0400
- Received: by kong.gsfc.nasa.gov (4.1/SMI-4.1)id AA07425; Mon, 27 Apr 92 11:07:28 EDT
- Newsgroups: comp.sources.unix
- Path: vesper
- XFrom: vesper@kong.gsfc.nasa.gov (Greg Vesper - 520.9)
- Subject: Cputt - Version 2.3
- Message-Id: <1992Apr27.150723.7382@kong.gsfc.nasa.gov>
- Sender: vesper@kong.gsfc.nasa.gov (Greg Vesper - 520.9)
- Organization: Goddard Space Flight Center
- Date: Mon, 27 Apr 92 15:07:23 GMT
- Lines: 688
- Apparently-To: comp-sources-unix@uunet.uu.net
- X
- This is the latest version of 'cputt' - a cpu monitoring utility for SunOS
- X4.1.1. It contains an important bug fix which allows it run on Sun 3's.
- X
- END_OF_FILE
- if test 1160 -ne `wc -c <'UNSHAR.HDR'`; then
- echo shar: \"'UNSHAR.HDR'\" unpacked with wrong size!
- fi
- # end of 'UNSHAR.HDR'
- fi
- if test -f 'cputt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cputt.c'\"
- else
- echo shar: Extracting \"'cputt.c'\" \(7269 characters\)
- sed "s/^X//" >'cputt.c' <<'END_OF_FILE'
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/timeb.h>
- X#include <sys/user.h>
- X#include <sys/resource.h>
- X#include <kvm.h>
- X#include <fcntl.h>
- X
- X#include "cputt.h"
- X
- X/*
- X MAIN - Computes CPU utilization for all processes from two snapshots
- X of the kernel process table taken over a user supplied interval
- X (arg1). Sorts and prints the top ten CPU using processes for that
- X interval. Execution continues for a user supplied number of
- X iterations (arg2).
- X
- X The kernel process table snapshots are stored in two arrays,
- X 'oldproc' and 'newproc'. Resource utilization information is stored
- X in two arrays, 'oldusage' and 'newusage'. The command strings for
- X each process are stored in a 2D array, 'cmds'. CPU utilization for
- X each interval is stored in the 'sdata' array along with pointers to
- X the appropriate 'proc' and 'cmds' entries.
- X*/
- X
- main (argc, argv)
- X
- int argc; char *argv[];
- X
- X{
- X struct proc *oldproc,*newproc,*tproc;
- X struct rusage *oldusage,*newusage,*tusage;
- X struct sortdata *sdata;
- X struct hashtab *hp;
- X
- X register long time1,utime1,time2,utime2;
- X register long s_delta,p_delta;
- X register int i,last,sindex;
- X
- X struct timeb ot,nt;
- X struct hashtab *hashuid();
- X int reps,interval,iterations,cmp();
- X double percentmem();
- X char **cmds;
- X
- X /* check arguements */
- X
- X switch(argc)
- X {
- X case 3:
- X interval = atoi(argv[1]);
- X iterations = atoi(argv[2]);
- X break;
- X case 1:
- X interval=5;
- X iterations=10;
- X break;
- X default:
- X printf("Usage: cputt <interval> <iterations>\n");
- X exit(1);
- X }
- X
- X setpriority(PRIO_PROCESS,0,-20);
- X
- X /* open kernel memory */
- X
- X if(!(Flkvm = kvm_open(NULL, NULL, NULL, O_RDONLY, "cputt")))
- X exit(1);
- X
- X /* get critical system parameters, build uid hash table */
- X
- X printf("Initializing..\n");
- X init();
- X initusers();
- X
- X /* truncate unused portion of the process table */
- X
- X Info.i_sproc = Info.i_nproc * sizeof(struct proc);
- X if (GROWTH_BUF)
- X {
- X oldproc = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
- X readstatus(oldproc);
- X for (i=0; i<Info.i_nproc; i++)
- X if (oldproc[i].p_stat && getupage(&oldproc[i]))
- X {
- X last=i;
- X }
- X free(oldproc);
- X if (last+GROWTH_BUF < Info.i_nproc)
- X {
- X Info.i_nproc = last+GROWTH_BUF;
- X Info.i_sproc = Info.i_nproc * sizeof(struct proc);
- X }
- X }
- X
- X /* allocate core for internal data structures */
- X cmds = (char **) getcore(Info.i_nproc*sizeof(char *));
- X for (i=0;i<Info.i_nproc;i++)
- X cmds[i] = (char *) getcore(COMMAND_SIZE);
- X
- X sdata = (struct sortdata *)
- X getcore(MAXACTIVE*sizeof(struct sortdata));
- X oldusage = (struct rusage *)
- X getcore(Info.i_nproc*sizeof(struct rusage));
- X newusage = (struct rusage *)
- X getcore(Info.i_nproc*sizeof(struct rusage));
- X oldproc = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
- X newproc = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
- X
- X /* get initial time, process table, upage, and command strings */
- X
- X ftime(&ot);
- X readstatus(oldproc);
- X for (i=0;i<Info.i_nproc;i++)
- X if (oldproc[i].p_stat && getupage(&oldproc[i]))
- X {
- X oldusage[i] = User.u_us.u_ru;
- X getcmd(&oldproc[i],cmds[i]);
- X }
- X
- X /* compare process tables every argv[1] seconds for argv[2] iterations */
- X
- X for (reps = 0; reps < iterations; reps++)
- X {
- X sleep(interval); /* sleep for agrv[1] seconds */
- X ftime(&nt); /* get new time */
- X readstatus(newproc); /* get new process table */
- X
- X /* find matching pids, compute cpu usage, store results in sdata */
- X
- X for (sindex=i=0; i<Info.i_nproc; i++)
- X if (newproc[i].p_stat && getupage(&newproc[i]))
- X {
- X last=i; /* record latest proc table location */
- X newusage[i] = User.u_us.u_ru;
- X if (oldproc[i].p_pid==newproc[i].p_pid)
- X {
- X time1 = oldusage[i].ru_utime.tv_sec +
- X oldusage[i].ru_stime.tv_sec;
- X utime1 = oldusage[i].ru_utime.tv_usec +
- X oldusage[i].ru_stime.tv_usec;
- X time2 = newusage[i].ru_utime.tv_sec +
- X newusage[i].ru_stime.tv_sec;
- X utime2 = newusage[i].ru_utime.tv_usec +
- X newusage[i].ru_stime.tv_usec;
- X p_delta = (time2*1000000+utime2) -
- X (time1*1000000+utime1);
- X if (p_delta)
- X {
- X s_delta = (nt.time*1000+nt.millitm) -
- X (ot.time*1000+ot.millitm);
- X sdata[sindex].pctcpu = (p_delta*10)/s_delta;
- X sdata[sindex].proc = &oldproc[i];
- X sdata[sindex].pr_cmd = i;
- X
- X if (sindex < MAXACTIVE - 1)
- X sindex++;
- X else
- X printf("\ncputt: MAXACTIVE limit exceeded.\n");
- X }
- X }
- X else
- X {
- X getcmd(&newproc[i],cmds[i]);
- X }
- X }
- X
- X /* check process table variance at each iteration */
- X
- X if (GROWTH_BUF &&
- X (i-last < GROWTH_BUF-MAX_GROW || i-last > GROWTH_BUF+MAX_SHRINK))
- X {
- X printf("\nProcess table variance greater than %d, restarting..\n",
- X MAX_GROW + MAX_SHRINK);
- X execvp(argv[0],argv);
- X }
- X
- X /* sort and print results */
- X
- X qsort(sdata,sindex,sizeof(struct sortdata),cmp);
- X printf("\n PID USER CPU MEM COMMANDS - %d %d\n"
- X ,sindex,last);
- X for (i=--sindex; sindex > -1 && sindex > i-MAXOUT; --sindex)
- X {
- X printf("%5d ",sdata[sindex].proc->p_pid);
- X if (hp = hashuid(sdata[sindex].proc->p_suid))
- X printf("%-8.8s ",hp->h_uname);
- X else
- X printf("user%-4.4d ",sdata[sindex].proc->p_uid);
- X printf("%6.2f ",(float)sdata[sindex].pctcpu/100);
- X printf("%6.2f ",percentmem(sdata[sindex].proc));
- X printf(" %s\n",cmds[sdata[sindex].pr_cmd]);
- X }
- X
- X /* swap old and new pointers */
- X
- X tusage = oldusage; tproc = oldproc;
- X oldusage = newusage; oldproc = newproc;
- X newusage = tusage; newproc = tproc;
- X ot = nt;
- X
- X } /* for all iterations.. */
- X
- X} /* main */
- END_OF_FILE
- if test 7269 -ne `wc -c <'cputt.c'`; then
- echo shar: \"'cputt.c'\" unpacked with wrong size!
- fi
- # end of 'cputt.c'
- fi
- if test -f 'cputt.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cputt.h'\"
- else
- echo shar: Extracting \"'cputt.h'\" \(2203 characters\)
- sed "s/^X//" >'cputt.h' <<'END_OF_FILE'
- X#define MAXUSERS 300 /* set this to (length of /etc/passwd * 2) */
- X#define MAXACTIVE 50 /* max cpu-positive processes per interval */
- X#define MAXOUT 10 /* output is limitted to this many processes */
- X#define COMMAND_SIZE 51 /* set this to (width of your window - 29) */
- X#define UNAMELEN 8 /* max length for username */
- X
- X/*
- X cputt attempts to truncate unused slots at the end of the process
- X table. This usually reduces its runtime size considerably. If the
- X process table grows or shrinks by a significant amount, cputt will
- X restart itself and resize its internal data structures accordingly.
- X*/
- X
- X#define GROWTH_BUF 40 /* growth buffer, use 0 to disable truncation */
- X#define MAX_GROW 20 /* restart after proc table grows this much */
- X#define MAX_SHRINK 10 /* restart after proc table shrinks this much */
- X
- X/* Symbol table entry and value */
- X
- struct symbol
- X{
- X char *s_kname; /* kernel symbol name */
- X caddr_t *s_info; /* kernel symbol value */
- X};
- X
- X/* Single hash table entry for mapping uid's to usernames */
- X
- struct hashtab
- X{
- X short h_uid; /* uid of user entry */
- X char h_uname[UNAMELEN]; /* corresponding name */
- X};
- X
- X/* Critical system info */
- X
- struct info
- X{
- X struct proc *i_proc0; /* address of process table */
- X int i_nproc; /* length of process table */
- X int i_sproc; /* size of process table */
- X int i_ecmx; /* max physical memory address*/
- X struct hashtab i_hnames[MAXUSERS]; /* hash table for usernames */
- X};
- X
- X/* For reading process upages from kernel memory */
- X
- union userstate
- X{
- X struct user u_us;
- X char u_pg[UPAGES][NBPG];
- X};
- X
- X/* Summary info for processes with positive cpu utilization */
- X
- struct sortdata
- X{
- X struct proc *proc; /* proc structure */
- X long pctcpu; /* cpu usage */
- X int pr_cmd; /* command string index */
- X};
- X
- extern kvm_t *Flkvm;
- extern union userstate User;
- extern struct symbol Symbollist[];
- extern struct info Info;
- END_OF_FILE
- if test 2203 -ne `wc -c <'cputt.h'`; then
- echo shar: \"'cputt.h'\" unpacked with wrong size!
- fi
- # end of 'cputt.h'
- fi
- if test -f 'getcmd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'getcmd.c'\"
- else
- echo shar: Extracting \"'getcmd.c'\" \(1031 characters\)
- sed "s/^X//" >'getcmd.c' <<'END_OF_FILE'
- X#include <sys/user.h>
- X#include <kvm.h>
- X#include "cputt.h"
- X
- X/* GETCMD - gets the command string for process p and copies it to argbuf */
- X
- void
- getcmd(p,argbuf)
- struct proc *p;
- register char *argbuf;
- X{
- X register char *cp,**ap;
- X char **argv;
- X register int sp=-1;
- X
- X if (!p->p_pid)
- X { strcpy(&argbuf[0],"Swapper"); return; }
- X if (p->p_pid == 2)
- X { strcpy(&argbuf[0],"Pager"); return; }
- X
- X if (kvm_getcmd(Flkvm,p,&User.u_us,&argv,(char ***)NULL)<0||argv==NULL)
- X {
- X argbuf[0] = '(';
- X strncpy(&argbuf[1],User.u_us.u_comm,sizeof(User.u_us.u_comm));
- X argbuf[sizeof(User.u_us.u_comm)+1] = '\0';
- X strcat(argbuf,")");
- X }
- X else
- X {
- X ap = argv;
- X while (*ap && sp < COMMAND_SIZE-1)
- X {
- X for (cp = *ap++; *cp && sp < COMMAND_SIZE-2;)
- X argbuf[++sp] = *cp++;
- X argbuf[++sp] = ' ';
- X }
- X argbuf[sp] = '\0';
- X free(argv);
- X }
- X}
- END_OF_FILE
- if test 1031 -ne `wc -c <'getcmd.c'`; then
- echo shar: \"'getcmd.c'\" unpacked with wrong size!
- fi
- # end of 'getcmd.c'
- fi
- if test -f 'globals.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'globals.c'\"
- else
- echo shar: Extracting \"'globals.c'\" \(627 characters\)
- sed "s/^X//" >'globals.c' <<'END_OF_FILE'
- X#include <sys/user.h>
- X#include <kvm.h>
- X#include "cputt.h"
- X
- struct info Info; /* System Addresses and Info */
- X
- kvm_t *Flkvm; /* Descriptor for Kernel Memory */
- X
- union userstate User; /* Structure to Hold Upages */
- X
- struct symbol Symbollist[] = /* Symbols to Lookup */
- X{
- X { "_proc", (caddr_t*)&Info.i_proc0 }, /* Process table base */
- X { "_nproc", (caddr_t*)&Info.i_nproc }, /* Max number of processes */
- X { "_maxmem",(caddr_t*)&Info.i_ecmx }, /* Max real memory */
- X { (char*)0, (caddr_t*)0 } /* NULL entry */
- X};
- END_OF_FILE
- if test 627 -ne `wc -c <'globals.c'`; then
- echo shar: \"'globals.c'\" unpacked with wrong size!
- fi
- # end of 'globals.c'
- fi
- if test -f 'hash.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'hash.c'\"
- else
- echo shar: Extracting \"'hash.c'\" \(1001 characters\)
- sed "s/^X//" >'hash.c' <<'END_OF_FILE'
- X#include <sys/user.h>
- X#include <kvm.h>
- X#include <pwd.h>
- X#include "cputt.h"
- X
- X#define HASHFN1(a) (((unsigned)(a)*91 + 17) % MAXUSERS)
- X
- X/*
- X HASHUID - Returns a pointer to a slot in the hash table that corresponds
- X to the hash table entry for `uid'. It returns a null pointer if there is
- X no such slot.
- X*/
- X
- struct hashtab *
- hashuid(uid)
- int uid;
- X{
- X struct hashtab *hp;
- X
- X hp = &Info.i_hnames[HASHFN1(uid)];
- X if (hp->h_uid == uid)
- X return(hp);
- X return(0);
- X}
- X
- X/*
- X INITUSERS - builds the uid hash table.
- X*/
- X
- void
- initusers ()
- X{
- X struct passwd *pw;
- X struct hashtab *hp;
- X struct passwd *getpwent();
- X
- X while (pw = getpwent())
- X {
- X /* Try to find a free slot in the hash table and fill it. */
- X
- X hp = &Info.i_hnames[HASHFN1(pw->pw_uid)];
- X if (!hp->h_uname[0])
- X {
- X hp->h_uid = pw->pw_uid;
- X strncpy(hp->h_uname,pw->pw_name,UNAMELEN);
- X }
- X }
- X endpwent();
- X}
- END_OF_FILE
- if test 1001 -ne `wc -c <'hash.c'`; then
- echo shar: \"'hash.c'\" unpacked with wrong size!
- fi
- # end of 'hash.c'
- fi
- if test -f 'init.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'init.c'\"
- else
- echo shar: Extracting \"'init.c'\" \(1547 characters\)
- sed "s/^X//" >'init.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <nlist.h>
- X#include <sys/file.h>
- X#include <sys/user.h>
- X#include <kvm.h>
- X
- X#include "cputt.h"
- X
- X/*
- X INIT - Gets symbol table values for symbols in Symbollist.
- X*/
- X
- void
- init()
- X{
- X register struct nlist *np;
- X register struct symbol *s;
- X register struct nlist *np0;
- X char *getcore();
- X
- X /* find length of the list of desired symbols */
- X for (s = Symbollist; s->s_kname; s++);
- X
- X /* allocate core for nlist array */
- X np0 = (struct nlist*)getcore((s-Symbollist+1)*sizeof(struct nlist));
- X
- X /* initialize nlist array */
- X for (s = Symbollist,np = np0; s->s_kname; s++,np++)
- X {
- X np->n_name = s->s_kname;
- X np[1].n_name = (char*)0;
- X np->n_value = 0;
- X }
- X
- X /* read symbols from symbol table into nlist array */
- X if (kvm_nlist(Flkvm,np0) == -1)
- X {
- X fprintf(stderr,"sps - Can't read symbol file \n");
- X sysperror();
- X }
- X
- X /* derive system info from nlist and store in Symbollist */
- X for (s = Symbollist,np = np0; s->s_kname; s++,np++)
- X {
- X if (!np->n_value)
- X {
- X fprintf( stderr, "sps - Can't find symbol %s in %s", np->n_name);
- X *s->s_info = (caddr_t)0;
- X continue;
- X }
- X
- X /* Using the obtained address, read the value into Symbollist */
- X (void)getkmem((long)np->n_value, (char*)s->s_info, sizeof(caddr_t));
- X }
- X free((char*)np0);
- X}
- END_OF_FILE
- if test 1547 -ne `wc -c <'init.c'`; then
- echo shar: \"'init.c'\" unpacked with wrong size!
- fi
- # end of 'init.c'
- fi
- if test -f 'routines.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'routines.c'\"
- else
- echo shar: Extracting \"'routines.c'\" \(2263 characters\)
- sed "s/^X//" >'routines.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <sys/user.h>
- X#include <kvm.h>
- X#include "cputt.h"
- X
- X/*
- X GETUPAGE - Reads the upage for the specified process as well as sufficient
- X page tables entries for reading the command arguments. The pte's are read
- X into the argument `p'. The upage is read into the external variable
- X `User'. Returns 1 if the upage was successfully read.
- X*/
- X
- getupage(p)
- register struct proc *p;
- X{
- X struct user *upage;
- X
- X if (upage = kvm_getu(Flkvm,p))
- X {
- X bcopy((char *)upage,User.u_pg[0],sizeof(struct user));
- X return(1);
- X }
- X/*
- X fprintf(stderr,"cputt - Can't read upage of process %d s= %o f= %o\n",
- X p->p_pid,p->p_stat,p->p_flag) ;
- X*/
- X return(0);
- X}
- X
- X/* READSTATUS - Reads process table from kernel memory */
- X
- void
- readstatus(ptable)
- struct proc *ptable;
- X{
- X if (getkmem((long)Info.i_proc0,(char*)ptable,Info.i_sproc)!=Info.i_sproc)
- X {
- X fprintf(stderr,"cputt - Can't read system process table\n" );
- X exit();
- X }
- X}
- X
- X/* PERCENTMEM - Returns the percentage of real memory used by this process */
- X
- double
- percentmem(p)
- struct proc *p;
- X{
- X double fracmem;
- X
- X if (!(p->p_flag & SLOAD))
- X return (0.0);
- X fracmem = ((double)p->p_rssize + UPAGES);
- X return(100.0 * fracmem / (double)Info.i_ecmx);
- X}
- X
- X/* GETKMEM - read kernel memory */
- X
- getkmem(addr,buf,bufsize)
- long addr;
- char *buf;
- int bufsize;
- X{
- X return(kvm_read(Flkvm,(long)addr,buf,bufsize));
- X}
- X
- X/* SYSPERROR - Reports a system defined error msg and then exits gracefully */
- X
- void
- sysperror ()
- X{
- X extern int errno;
- X extern int sys_nerr;
- X extern char *sys_errlist[];
- X
- X if (0 < errno && errno < sys_nerr)
- X fprintf(stderr," : %s",sys_errlist[errno]);
- X (void)fputc('\n',stderr);
- X exit(1);
- X}
- X
- X/* GETCORE - Allocate and return a pointer to the asked for amount of core */
- X
- char *
- getcore(size)
- register int size ;
- X{
- X register char *chp;
- X char *malloc();
- X
- X if (chp = malloc((unsigned)size))
- X return(chp);
- X fprintf(stderr,"cputt - Out of core");
- X sysperror();
- X}
- X
- X/* CMP - used by qsort() to perform comparisons */
- X
- cmp(p1,p2)
- register struct sortdata *p1,*p2;
- X{
- X return(p1->pctcpu - p2->pctcpu);
- X}
- END_OF_FILE
- if test 2263 -ne `wc -c <'routines.c'`; then
- echo shar: \"'routines.c'\" unpacked with wrong size!
- fi
- # end of 'routines.c'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-